package cn.com.cpic.insurance.rulecheck.service;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.cpic.insurance.rulecheck.entity.Rule;
import cn.com.cpic.insurance.rulecheck.entity.RuleDefinitionItem;
import cn.com.cpic.insurance.rulecheck.entity.RuleItem;

@Service
@Transactional
public class RuleService {

	private JdbcTemplate jdbcTemplate;

	private RuleItemService service3;

	private RuleDefinitionItemService service1;

	@Transactional(readOnly = true)
	public List<Rule> getRuleList(final Long conditionId) {
		return jdbcTemplate.query("SELECT * FROM t_rc_rule WHERE c_condition_id=? ORDER BY c_id",
				new Object[] { conditionId },
				new RowMapper<Rule>() {
					public Rule mapRow(ResultSet rs, int index)
							throws SQLException {
						Rule item = new Rule();
						item.setId(rs.getLong("c_id"));
						item.setConditionId(conditionId);
						item.setRuleDefinitionId(rs.getLong("c_rule_def_id"));
						item.setName(rs.getString("c_name"));
						item.setRemark(rs.getString("c_rem"));
						return item;
					}
				});
	}

	@Transactional(readOnly = true)
	public Rule getRule(final Long id) {
		return jdbcTemplate.query("SELECT * FROM t_rc_rule WHERE c_id=?",
				new Object[] { id }, new ResultSetExtractor<Rule>() {
					public Rule extractData(ResultSet rs)
							throws SQLException, DataAccessException {
						rs.next();
						Rule item = new Rule();
						item.setId(id);
						item.setConditionId(rs.getLong("c_condition_id"));
						item.setRuleDefinitionId(rs.getLong("c_rule_def_id"));
						item.setName(rs.getString("c_name"));
						item.setRemark(rs.getString("c_rem"));
						return item;
					}
				});
	}

	public long saveRule(final Rule item) {
		if (item.getId() == null) {
			jdbcTemplate.update(
					"INSERT INTO t_rc_rule VALUES(nextval('seq_id'),?,?,?,?)",
					new PreparedStatementSetter() {
						public void setValues(PreparedStatement ps)
								throws SQLException {
							ps.setLong(1, item.getConditionId());
							ps.setLong(2, item.getRuleDefinitionId());
							ps.setString(3, item.getName());
							ps.setString(4, item.getRemark());
						}
					});
			return jdbcTemplate.queryForLong("SELECT currval('seq_id')");
		} else {
			jdbcTemplate.update(
					"UPDATE t_rc_rule SET c_condition_id=?,c_rule_def_id=?,c_name=?,c_rem=? WHERE c_id=?",
					new PreparedStatementSetter() {
						public void setValues(PreparedStatement ps)
								throws SQLException {
							ps.setLong(1, item.getConditionId());
							ps.setLong(2, item.getRuleDefinitionId());
							ps.setString(3, item.getName());
							ps.setString(4, item.getRemark());
							ps.setLong(5, item.getId());
						}
					});
			return item.getId();
		}
	}

	public void deleteRule(final Long id) {
		jdbcTemplate.update("DELETE FROM t_rc_rule WHERE c_id=?", id);
	}

	public void copyRuleItemsFromDef(final Long id, final Long ruleDefId) {
		jdbcTemplate.update("DELETE FROM t_rc_rule_item WHERE c_rule_id=?", id);
		List<RuleDefinitionItem> items = service1.getRuleDefinitionItemList(ruleDefId);
		for (RuleDefinitionItem def : items) {
			RuleItem item = new RuleItem();
			item.setRuleId(id);
			item.setParamName(def.getParamName());
			item.setRemark(def.getRemark());
			service3.saveRuleItem(item);
		}
	}

	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	@Autowired
	public void setService1(RuleDefinitionItemService service1) {
		this.service1 = service1;
	}

	@Autowired
	public void setService2(RuleItemService service) {
		this.service3 = service;
	}
}
